home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / sbvoicj.lzh / SBVOICE.PAS < prev   
Pascal/Delphi Source File  |  1991-03-31  |  11KB  |  351 lines

  1. {---------------------------------------------------------------------------
  2.                    Unit SBVoice (v1.11) for Turbo Pascal 6.0
  3.        For interfacing with the SoundBlaster's digitized voice channel.
  4.            Copyright (c) 1991, Amit K. Mathur, Windsor, Ontario.
  5.  
  6.                         By: Amit K. Mathur
  7.                             3215 St. Patrick's Drive
  8.                             Windsor, Ontario
  9.                             N9E 3H2 CANADA
  10.                         Ph: (519) 966-6924
  11.  
  12.  Networks:  RIME(tm) R/O ->WINDSOR, ILink (Shareware), NA-Net (Pascal),
  13.             WWIVNet (#12@5957), or direct on NorthSTAR (519)735-1504.
  14.  
  15.  These routines are released to the public domain.  However I will gladly
  16.  accept contributions towards further development of this and other products.
  17.  I cannot devote time to these products unless I receive some response
  18.  from you, the user.  Support strugling University students!
  19.  Please send any changes or improvements my way.  And I'm interested in
  20.  other SoundBlaster utilities and programming tools.  Thanks in advance.
  21.  --------------------------------------------------------------------------}
  22.  
  23. {$O+,F+}
  24. { Allow this Unit to Be Overlayed (doesn't affect compilation if you decide
  25.   not to overlay it), and force far calls.                                 }
  26.  
  27. unit SBVoice;
  28.  
  29. interface
  30.  
  31. uses MemAlloc;                                    { Memory Allocation Proc }
  32.  
  33. var
  34. {$IFNDEF NoSBVoiceArray}                          { to use your own        }
  35.      SoundFile: Array[1..25000] of byte;          { whatever size you want }
  36. {$ENDIF}
  37.      sgSBDriver, ofSBDriver: word;                { seg and ofs of Driver  }
  38.      SBDriver: Pointer;                           { pointer to the driver  }
  39.      StatusWord: Word;                            { stores SB status       }
  40.      SBFound: Boolean;                            { whether Init worked    }
  41.  
  42. procedure loaddriver(fi:string);
  43. { Loads CT-VOICE.DRV into memory.  'fi' is the path to the driver.         }
  44.  
  45. procedure closedriver;
  46. { Clean up routine.  Not really necessary if your program is over.         }
  47.  
  48. procedure loadvoice(f:string;start,size:word);
  49. { Load 'f' into memory.  Start is the start of the area within
  50.   'f' to load and size is the amount to laod.  If you set size to 0
  51.   then it will load the entire file.                                      }
  52.  
  53. function sb_getversion:integer;
  54. { Get the version number of the CT-VOICE.DRV
  55.   Returns the Version number                                              }
  56.  
  57. function sb_init:integer;
  58. { Initialize the SoundBlaster.  Call this right after load driver, unless
  59.   you have to change the BaseIOAddress or Interrupt number and haven't
  60.   changed the CT-VOICE.DRV file itself.
  61.   Returns:  0 - no problem
  62.             1 - sound card failiure
  63.             2 - I/O failiure
  64.             3 - DMA interrupt failiure                                    }
  65.  
  66. procedure sb_output(sg,os:word);
  67. { Output the digitized sound.  You must load the sound first!
  68.   sg and os are the segment and offset of either SoundFile or whatever
  69.   array you use to store the sound.  If you use a .VOC file then call
  70.   with 26 added to the offset.                                            }
  71.  
  72. procedure sb_setstatusword(sg,os:word);
  73. { Sets the location of the status word.  This is the third thing you should
  74.   do, after loading the driver and initializing it.
  75.   The StatusWord will contain $0FFFF if input/output is in output, and
  76.   0 when it's done.  It will also hold the values of the markers in voice
  77.   files if any are encounterred, allowing you to coordinate output with
  78.   your programs.                                                          }
  79.  
  80. procedure sb_speaker(mode:word);
  81. { Set the speaker on/off.  Off is mode 0, and On is anything else.  This
  82.   is the fourth thing you should do in your initialization.               }
  83.  
  84. procedure sb_uninstall;
  85. { Uninstall the driver from memory.   Used by CloseDriver.                }
  86.  
  87. procedure sb_setIOaddress(add:word);
  88. { Override the IOaddress found inside the CT-VOICE.DRV file.  Add is the
  89.   new IO address.                                                         }
  90.  
  91. procedure sb_setinterruptnumber(intno:word);
  92. { Allows you to override the Interrupt number in the driver.  IntNo is your
  93.   new interrupt number (3, 5, 7 or 9).                                    }
  94.  
  95. procedure sb_stopoutput;
  96. { Stops the output in progress                                            }
  97.  
  98. function sb_pauseoutput: integer;
  99. { Pauses the output in progress.
  100.   Returns:  0 - success
  101.             1 - fail                                                      }
  102.  
  103. function sb_continueoutput: integer;
  104. { Continues a paused output.
  105.   Returns:  0 - success
  106.             1 - fail (nothing to continue)                                }
  107.  
  108. function sb_breakloop(mode:word): integer;
  109. { Breaks out of the currect output loop.
  110.   Modes:  0 - continue round, stop when done
  111.           1 - stop immediately
  112.   Returns:  0 - success
  113.             1 - not in loop                                               }
  114.  
  115. procedure sb_input(highlength,lowlength,seginputbuff,ofsinputbuff:word);
  116. { Input digitized sound.
  117.   HighLength: The high byte of the length of the input buffer.
  118.   LowLength:  The low byte of the length of the input buffer.
  119.   SegInputBuff: The Segment of the start of the input buffer.
  120.   OfsInputBuff: The Offset of the start of the input buffer.              }
  121.  
  122. procedure sb_setuserfunction(segaddress,ofsaddress:word);
  123. { Sets up a user function that the SB calls when it encounters a new data
  124.   block.  It must perform a FAR ret, preserve DS,DI,SI and flag register.
  125.   Clear Carry flag if you want the driver to process the block, or set it
  126.   if your routine will.  It must be clear if the block type is 0, that
  127.   is the terminate block.
  128.   SegAddress is the segment of your user function in memory.
  129.   OfsAddress is the ofset of your user function in memory.                }
  130.   
  131. implementation
  132.  
  133. uses DOS;
  134.  
  135. procedure Abort(s:string);
  136. begin
  137.   writeln('The Following Error Has Occurred: ',s);
  138.   writeln('Remedy and try again.  We apologize for any inconvenience.');
  139.   halt(1);
  140. end;
  141.  
  142. procedure loaddriver(fi:string);
  143. var f: file;
  144.     k: integer;
  145.     t: string[8];
  146. begin
  147.     assign(f,fi+'CT-VOICE.DRV');
  148.     {$I-} Reset(f,1); {$I+}
  149.     if IOResult <> 0 then
  150.         Abort('Cannot Open '+fi+'CT-VOICE.DRV');
  151.     blockread(f,Mem[sgSBDriver:ofSBDriver],filesize(f));
  152.     close(f);
  153.     t:='';
  154.     for k:=0 to 7 do
  155.         t:=t+chr(Mem[sgSBDriver:ofSBDriver+k+3]);
  156.     if t<>'CT-VOICE' then
  157.         abort('Invalid CT-VOICE Driver!');
  158. end;
  159.  
  160. procedure closedriver;
  161. begin
  162.     sb_uninstall;
  163.     if dalloc(sbdriver)=0 then
  164.         abort('Uninstall Error!');
  165. end;
  166.  
  167. procedure loadvoice(f:string;start,size:word);
  168. var fi: file;
  169.     k: word;
  170. begin
  171.     assign(fi,f);
  172.     {$I-} Reset(fi,1); {$I+}
  173.     if IOResult <> 0 then
  174.        abort('Cannot Open '+f+'!');
  175.     k:=0;
  176.     seek(fi,start);
  177.     if size=0 then size:=filesize(fi);
  178.     blockread(fi,Mem[seg(soundfile):ofs(soundfile)],size);
  179.     close(fi);
  180. end;
  181.  
  182. function sb_getversion: integer; assembler;
  183. asm
  184.    push  bp
  185.    mov   bx,0
  186.    call  SBDriver
  187.    pop   bp
  188. end;
  189.  
  190. procedure sb_setIOaddress(add:word); assembler;
  191. asm
  192.    push  bp
  193.    mov   bx,1
  194.    mov   ax,add
  195.    call  SBDriver
  196.    pop   bp
  197. end;
  198.  
  199. procedure sb_setinterruptnumber(intno:word); assembler;
  200. asm
  201.    push  bp
  202.    mov   bx,2
  203.    mov   ax,intno
  204.    call  SBDriver
  205.    pop   bp
  206. end;
  207.  
  208. procedure sb_stopoutput; assembler;
  209. asm
  210.    push  bp
  211.    mov   bx,8
  212.    call  SBDriver
  213.    pop   bp
  214. end;
  215.  
  216. function sb_init: integer; assembler;
  217. asm
  218.    push  bp
  219.    mov   bx, 3
  220.    call  SBDriver
  221.    pop   bp
  222. end;
  223.  
  224. function sb_pauseoutput: integer; assembler;
  225. asm
  226.    push  bp
  227.    mov   bx,10
  228.    call  SBDriver
  229.    pop   bp
  230. end;
  231.  
  232. function sb_continueoutput: integer; assembler;
  233. asm
  234.    push  bp
  235.    mov   bx,11
  236.    call  SBDriver
  237.    pop   bp
  238. end;
  239.  
  240. function sb_breakloop(mode:word): integer; assembler;
  241. asm
  242.    push  bp
  243.    mov   bx,12
  244.    mov   ax,mode
  245.    call  SBDriver
  246.    pop   bp
  247. end;
  248.  
  249. procedure sb_output(sg,os:word); assembler;
  250. asm
  251.     push bp
  252.     push di
  253.     mov  bx,6
  254.     mov  di,os             { offset of voice  }
  255.     mov  es,sg             { segment of voice }
  256.     call SBDriver
  257.     pop  di
  258.     pop  bp
  259. end;
  260.  
  261. procedure sb_input(highlength,lowlength,seginputbuff,ofsinputbuff:word); assembler;
  262. asm
  263.     push bp
  264.     push di
  265.     mov  bx,7
  266.     mov  dx,highlength
  267.     mov  cx,lowlength
  268.     mov  es,seginputbuff
  269.     mov  di,ofsinputbuff
  270.     call SBDriver
  271.     pop  di
  272.     pop  bp
  273. end;
  274.  
  275. procedure sb_setstatusword(sg,os:word); assembler;
  276. asm
  277.     push bp
  278.     push di
  279.     mov  bx,5
  280.     mov  di,os
  281.     mov  es,sg
  282.     call SBDriver
  283.     pop  di
  284.     pop  bp
  285. end;
  286.  
  287. procedure sb_speaker(mode:word); assembler;
  288. asm
  289.    push  bp
  290.    mov   bx,4
  291.    mov   ax,mode
  292.    call  SBDriver
  293.    pop   bp
  294. end;
  295.  
  296. procedure sb_uninstall; assembler;
  297. asm
  298.    push  bp
  299.    mov   bx,9
  300.    call  SBDriver
  301.    pop   bp
  302. end;
  303.  
  304. procedure sb_setuserfunction(segaddress,ofsaddress:word); assembler;
  305. asm
  306.    push  bp
  307.    mov   dx,segaddress
  308.    mov   ax,ofsaddress
  309.    mov   bx,13
  310.    call  SBDriver
  311.    pop   bp
  312. end;
  313.  
  314.  
  315. begin {set up SB}
  316.  
  317. {
  318.   In the following lines the number 2500 is used.  If you are using
  319.   a newer SoundBlaster, with a CT-Voice driver of greater than 2500 bytes,
  320.   then you MUST change this number or will experience Memory Allocation
  321.   Errors, and system lockups.  Increase the number to just above the size
  322.   of the CT-Voice driver you are using.
  323. }
  324.  
  325.   If DOSMemAvail < 2500 then                           { lower the heap   }
  326.       abort('Not Enough Memory');                      { with $M to fix   }
  327.   StatusWord:=MAlloc(SBDriver,2500);
  328.   if StatusWord<>0 then
  329.       abort('Memory Allocation Error');
  330.  
  331.   sgSBDriver:=MemW[seg(SBDriver):ofs(SBDriver)+2];
  332.   ofSBDriver:=MemW[seg(SBDriver):ofs(SBDriver)];
  333.  
  334. {
  335.   You may want to specifically set the interrupt number and IO Address using
  336.   the routines above to your card's settings.  You will not get any sound
  337.   or be able to use this unit unless the SoundBlaster IRQ is set right.
  338. }
  339.  
  340.   Loaddriver('');                                      { change at will   }
  341.   if sb_init<>0 then                                   { or stick in your }
  342.       SBFound:=FALSE                                   { own program init }
  343.   else
  344.       SBFound:=TRUE;
  345.  
  346.   if SBFound then begin
  347.       sb_setstatusword(seg(statusword),ofs(statusword));
  348.       sb_speaker(1);                                   { turn SB on       }
  349.   end;
  350. end.
  351.